#include "Tile.hpp"
#include "PenroseBasedSamplerConstants.hpp"
#include <iostream>

Tile& Tile::operator=(const Tile& tile_)
{
	if(this != &tile_)
	{
		this->setDirection(tile_.getDir());
		this->setTriangle(tile_.getTriangle());
		this->setScale(tile_.getScale());
		this->setType(tile_.getType());
		this->setFCode(tile_.getFCode());
	}

	return (*this);
}

Tile::Tile()
{
	m_eType      = TILE_UNKNOWN;
	m_iDirection = 0;
	m_dScale     = 1.0f;
	m_iFCode     = 0;
}

Tile::Tile(const Tile &tile)
{
	m_eType      = tile.m_eType;
	m_iDirection = tile.m_iDirection;
	m_dScale     = tile.m_dScale;
	m_iFCode     = tile.m_iFCode;
	m_triangle   = tile.getTriangle();
}

Tile::Tile(TILE_TYPE type, int &iDir, double &dScale, MTriangle &triangle)
{
	m_eType      = type;
	m_iDirection = iDir;
	m_dScale     = dScale;
	m_triangle   = triangle;
}

Tile::Tile(TILE_TYPE type, int &iDir, double &dScale, MVector2D &origin, unsigned int iNewBits)
{
	m_eType      = type;
	m_iDirection = iDir%20;
	m_dScale     = dScale;
	//m_triangle
	std::cout << std::endl << "! ! ! ! ! ! ! ! ! ! ! ! !" << std::endl << "Tile::Tile( ... )  - UNFINISHED CONSTRUCTOR - " << std::endl << "! ! ! ! ! ! ! ! ! ! !" << std::endl;
}

void Tile::reset()
{
	m_eType      = TILE_UNKNOWN;
	m_iDirection = 0;
	m_dScale     = 1.0;
	m_iFCode     = 0;
	m_triangle.reset();
}

void Tile::setType(TILE_TYPE type)
{
	m_eType = type;
}

void Tile::setDirection(int iDir)
{
	m_iDirection = iDir;
}

void Tile::setScale(double dScale)
{
	m_dScale = dScale;
}

void Tile::setTriangle(MTriangle triangle)
{
	m_triangle = triangle;
}

void Tile::setOrigin(const MVector2D& origin)
{
	m_triangle.setVertexA(origin);
	rebuildTriangle();
}

void Tile::setFCode(unsigned int iFCode)
{
	m_iFCode = iFCode;
}

void Tile::rebuildTriangle()
{
	MVector2D b_, c_;
	int iDir = getDir();

	switch(m_eType)
	{
	case TILE_UNKNOWN:
		return;

	case TILE_C:
	case TILE_D:
		// "skinny" triangles
		b_ = m_triangle.getVertexA() + vvect[iDir%20]*m_dScale;
		c_ = m_triangle.getVertexA() + vvect[(iDir+4)%20]*(PHI*m_dScale);
		break;

	case TILE_E:
	case TILE_F:
		// "fat" triangles
		b_ = m_triangle.getVertexA() + vvect[iDir%20]*(PHI2*m_dScale);
		c_ = m_triangle.getVertexA() + vvect[(iDir+2)%20]*(PHI*m_dScale);
		break;

	default:
		b_ = m_triangle.getVertexA() + vvect[iDir%20]*m_dScale;
		c_ = m_triangle.getVertexA() + vvect[(iDir+5)%20]*m_dScale;
	}

	m_triangle.setVertexB(b_);
	m_triangle.setVertexC(c_);
}

void Tile::reCreateTile(TILE_TYPE type, int &iDir, double &dScale, MTriangle &triangle)
{
	m_eType      = type;
	m_iDirection = iDir % 20;
	m_dScale     = dScale;
	m_triangle   = triangle;
}

void Tile::prePendToCode(unsigned int iNewBits)
{
}

bool Tile::isSamplingType() const
{
	bool bSuccess = false;

	if(m_eType == TILE_A || m_eType == TILE_B)
		bSuccess = true;

	return bSuccess;
}

unsigned int Tile::getFCode() const
{
	return m_iFCode;
}

const MTriangle& Tile::getTriangle() const
{
	return m_triangle;
}

int Tile::getDir() const
{
	return m_iDirection;
}

double Tile::getScale() const
{
	return m_dScale;
}

TILE_TYPE Tile::getType() const
{
	return m_eType;
}

//EOF

